#!/bin/bash
export PATH="/data/user/0/bin.mt.plus/files/term/bin:/data/backup_tools:$PATH"
# 压缩文件前缀
PRE=Z
API_BASE=https://open-api.123pan.com
PLATFORM=open_platform
PARENT_ID=0 # 父文件夹id
PAN123_CLIENT_ID=759*****c0e #  123pan client id
PAN123_CLIENT_SECRET=5e******087 # 123pan client secret
get_access_token() {
    # 检查必要的环境变量
    if [ -z "$PAN123TOKEN" ]; then
        if [ -z "$PAN123_CLIENT_ID" ] || [ -z "$PAN123_CLIENT_SECRET" ]; then
            echo "❌ No clientID/clientSecret found, and no access_token, exiting"
            exit 1
        fi
    else
        if [ -z "$PAN123_CLIENT_ID" ] || [ -z "$PAN123_CLIENT_SECRET" ]; then
            echo "⚠️ access_token 存在，但未提供 clientID/clientSecret，跳过刷新"
            return 0
        fi
    fi
    # 从.env文件中读取access_token
    if [ -f ./.env ]; then
        source ./.env
    fi
    echo "过期时间:$PAN123TOKEN_EXPIREDAT"
    if [ -n "$PAN123TOKEN" ]; then
        # 检查 access_token 是否过期
        expired_at=$(date -d "${PAN123TOKEN_EXPIREDAT%+*}" +%s)
        now=$(date +%s)
        if [ $expired_at -gt $now ]; then
            echo "✅ Access token is valid, skipping refresh"
            return 0
        fi
    fi

    # 发送请求获取新的access token
    response=$(curl -s -X POST \
        -H "Platform: $PLATFORM" \
        -d "clientID=$PAN123_CLIENT_ID&clientSecret=$PAN123_CLIENT_SECRET" \
        "$API_BASE/api/v1/access_token")

    # 解析响应
    access_token=$(echo "$response" | jq -r '.data.accessToken')
    expired_at=$(echo "$response" | jq -r '.data.expiredAt')

    echo  "$response"

    if [ -z "$access_token" ] || [ -z "$expired_at" ]; then
        echo "❌ 获取 access_token 失败"
        exit 1
    fi

    # 将新的token存入环境变量
cat <<EOF > ./.env
    PAN123TOKEN="$access_token"
    PAN123TOKEN_EXPIREDAT="$expired_at"
EOF
    source ./.env


    echo "Access token: $access_token"
    echo "Expired at: $expired_at"

    echo "✅ Access token refreshed successfully"
}

# 2. 创建预上传任务
create_preupload() {
    local json_data="{\"parentFileID\":\"$PARENT_ID\",\"filename\":\"$FILE_NAME\",\"size\":$FILE_SIZE,\"etag\":\"$MD5\",\"duplicate\":\"2\"}"
    curl -s -X POST "$API_BASE/upload/v1/file/create" \
        -H "Content-Type: application/json" \
        -H "Platform: $PLATFORM" \
        -H "Authorization: $AUTH_TOKEN" \
        -d "$json_data"
}

# 3. 获取上传URL
get_upload_url() {
    local preupload_id="$1"
    local slice_no="$2"
    
    local json_data="{\"preuploadID\":\"$preupload_id\",\"sliceNo\":$slice_no}"
    
    curl -s -X POST "$API_BASE/upload/v1/file/get_upload_url" \
        -H "Content-Type: application/json" \
        -H "Platform: $PLATFORM" \
        -H "Authorization: $AUTH_TOKEN" \
        -d "$json_data"
}

# 4. 上传分片
upload_chunk() {
    local upload_url="$1"
    local chunk_file="$2"
    
    # 使用 -w 获取HTTP状态码，-o 将响应体输出到变量
    response=$(curl -s -w "\n%{http_code}" -X PUT "$upload_url" \
        -H "Content-Type: application/octet-stream" \
        --data-binary @"$chunk_file")
    
    # 分离响应体和状态码
    http_code=$(echo "$response" | tail -n1)
    response_body=$(echo "$response" | sed '$d')
    # echo "HTTP状态码: $http_code"
    # echo "响应体: $response_body"
    # 返回状态码（通过返回值+全局变量）
    if [ "$http_code" -eq 200 ]; then
        echo "✅ $chunk_file http_code:$http_code"
        return 0
    else
        echo "❌ 上传失败 (HTTP $http_code)" >&2
        echo "$response_body" >&2
        return 1
    fi
}

# 列出已上传分片（用于校验）
list_upload_parts() {
    local preupload_id="$1"
    local json_data="{\"preuploadID\":\"$preupload_id\"}"
    
    curl -s -X POST \
        "$API_BASE/upload/v1/file/list_upload_parts" \
        -H "Content-Type: application/json" \
        -H "Platform: $PLATFORM" \
        -H "Authorization: $AUTH_TOKEN" \
        -d "$json_data"
}
# 确认上传完成
upload_complete() {
    local preupload_id="$1"
    local json_data="{\"preuploadID\":\"$preupload_id\"}"
    
    curl -s -X POST  \
        "$API_BASE/upload/v1/file/upload_complete" \
        -H "Content-Type: application/json" \
        -H "Platform: $PLATFORM" \
        -H "Authorization: $AUTH_TOKEN" \
        -d "$json_data"
}
# 异步结果查询
poll_async_result() {
    local preupload_id="$1"
    local json_data="{\"preuploadID\":\"$preupload_id\"}"

    curl -s -X POST \
        "$API_BASE/upload/v1/file/upload_async_result" \
        -H "Content-Type: application/json" \
        -H "Platform: open_platform" \
        -H "Authorization: $AUTH_TOKEN" \
        -d "$json_data"
}
upload() {
    AUTH_TOKEN="Bearer $PAN123TOKEN"
    FILE_PATH="$1"
    if [ ! -f "$FILE_PATH" ]; then
        echo "❌ 文件不存在"
        exit 1
    fi
    FILE_SIZE=$(stat -c%s "$FILE_PATH")
    MD5=$(md5sum "$FILE_PATH" | cut -d' ' -f1)
    FILE_NAME=$(basename "$FILE_PATH")

    # 创建预上传
    echo "🔄 创建预上传任务..."
    preupload_response=$(create_preupload)
    preupload_id=$(echo "$preupload_response" | jq -r '.data.preuploadID')
    CHUNK_SIZE=$(echo "$preupload_response" | jq -r '.data.sliceSize | tostring')
    reuse=$(echo "$preupload_response" | jq -r '.data.reuse | tostring')
    echo $preupload_response
    if [ -z "$preupload_response" ]; then
        echo "❌ 创建预上传任务失败"
        exit 1
    fi
    if [ "$reuse" = "true" ]; then
        echo "✅ 预上传任务已存在，跳过创建"
        exit 0
    else
        echo "✅ 创建预上传任务成功"
    fi
    if [ -z "$preupload_id" ]; then
        echo "❌ 创建预上传任务失败"
        exit 1
    fi
    echo "✅ 预上传ID: $preupload_id"

    # 主流程
    echo "🚀 开始文件分片上传流程"
    echo "📁 文件: $FILE_NAME"
    echo "📏 大小: $FILE_SIZE, $((FILE_SIZE/1024/1024))MB"
    # echo "🔢 分片大小: $CHUNK_SIZE, $((CHUNK_SIZE/1024/1024))MB"
    echo "🔢 分片大小: $CHUNK_SIZE, $(echo "scale=2; $CHUNK_SIZE / 1024 / 1024" | bc)MB"

    # 计算分片数量
    # total_chunks=$(( (FILE_SIZE + CHUNK_SIZE - 1) / CHUNK_SIZE ))
    total_chunks=$(echo "($FILE_SIZE + $CHUNK_SIZE - 1) / $CHUNK_SIZE" | bc)
    echo "🧩 总分片数: $total_chunks"

    # 分片上传
    i=1
    while [ $i -le $total_chunks ]; do
        echo "⏫ 上传分片 $i/$total_chunks..."
        
        # 获取上传URL
        upload_url_response=$(get_upload_url "$preupload_id" "$i")
        upload_url=$(echo "$upload_url_response" | jq -r '.data.presignedURL')
        echo "🔑 上传URL: $upload_url"
        
        # 创建临时分片文件
        chunk_file="${FILE_PATH}.part$i"
        dd if="$FILE_PATH" bs=$CHUNK_SIZE skip=$((i-1)) count=1 > "$chunk_file" 2>/dev/null
        
        # 上传分片
        echo "🚀 上传分片 $chunk_file..."
        upload_response=$(upload_chunk "$upload_url" "$chunk_file")
        
        # 清理临时文件
        #rm -f "$chunk_file"

        echo "✅ 分片 $i 上传完成"
        i=$((i + 1))
    done
    upload_complete_res=$(upload_complete  "$preupload_id")
    echo $upload_complete_res
    echo "🚀 等待文件上传完成..."
    while true; do
        sleep 5
        result=$(poll_async_result "$preupload_id")
        echo $result
        # {
        #     "code": 0,
        #     "message": "ok",
        #     "data": {
        #         "fileID": 14665463,
        #         "completed": true
        #     },
        #     "x-traceID": "f79fb151-8bb4-47fd-828a-d7d180a76b30_kong-db-5898fdd8c6-t5pvc"
        # }
        completed=$(echo "$result" | jq -r '.data.completed | tostring')
        if [ "$completed" = "true" ]; then
            echo "✅ 文件上传成功"
            # 清理临时文件
            rm -f "$FILE_PATH".part*
            break
        fi
    done
}
# 压缩文件夹
compress_folder() {
    local folder_path=$1
    # 文件名已时间命名
    zip_file="$PRE-$(date +%Y%m%d%H%M%S).zip"
    
    # 创建压缩文件
    zip -r $zip_file $folder_path
    
    # 删除原始文件夹
    #rm -rf "$folder_path"
    
    # 返回压缩文件路径
    echo "$zip_file"
}
get_access_token

if [ $# -eq 0 ]; then
    echo "Usage:  <file_path> <folder_path>"
    exit 1
fi
# 判断是否是文件夹
if [ -d "$1" ]; then
    compress_folder $1
    file=$zip_file
else
    file="$1"
fi
upload "$file"
